package com.flow.service.provider.toleration.computer.service.impl;

import com.flow.framework.common.exception.CheckedException;
import com.flow.framework.core.pojo.vo.PageVo;
import com.flow.framework.lock.helper.LockHelper;
import com.flow.framework.persistence.helper.TransactionHelper;
import com.flow.framework.persistence.persistence.page.Page;
import com.flow.framework.persistence.util.PagePoUtil;
import com.flow.service.facade.toleration.TolerationErrorCode;
import com.flow.service.facade.toleration.computer.pojo.dto.ComputerModuleDto;
import com.flow.service.facade.toleration.computer.pojo.vo.ComputerModuleVo;
import com.flow.service.provider.toleration.computer.convert.ComputerConverter;
import com.flow.service.provider.toleration.computer.persistence.service.IComputerPoService;
import com.flow.service.provider.toleration.computer.pojo.dto.ComputerDto;
import com.flow.service.provider.toleration.computer.pojo.dto.ComputerPageQueryDto;
import com.flow.service.provider.toleration.computer.pojo.po.Computer;
import com.flow.service.provider.toleration.computer.pojo.vo.ComputerVo;
import com.flow.service.provider.toleration.computer.service.IComputerService;
import com.flow.service.provider.toleration.enumeration.ComputerLockKeyEnum;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.Collections;

/**
 * 电脑业务服务实现
 *
 * @author luoguopiao
 * @version 0.0.1
 * @date 2023/5/2
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class ComputerServiceImpl implements IComputerService {

    private final IComputerPoService computerPoService;

    /**
     * 创建用户
     *
     * @param dto dto
     * @return
     */
    @Override
    public ComputerVo create(ComputerDto dto) {
        Computer computer = ComputerConverter.convertToPo(dto);
        Computer computerInDb = create(computer);
        return ComputerConverter.convertToVo(computerInDb);
    }

    private Computer create(Computer computer) {
        String computerCode = computer.getComputerCode();
        LockHelper.voidLockExecute(null, ComputerLockKeyEnum.COMPUTER_CODE_CHECK_LOCK_KEY,
                Collections.singletonList(computerCode), () -> {
                    boolean computerCodeExist = computerPoService.isComputerCodeExist(computerCode);
                    if (computerCodeExist) {
                        log.error("computer code exist, computer code : {}", computerCode);
                        throw new CheckedException(TolerationErrorCode.COMPUTER_CODE_EXIST_ERROR);
                    }
                    TransactionHelper.localNewTransactionVoidExec(() -> computerPoService.save(computer));
                });
        return computerPoService.getById(computer.getId(), false);
    }

    /**
     * 创建用户
     *
     * @param dto dto
     * @return
     */
    @Override
    public ComputerModuleVo create(ComputerModuleDto dto) {
        Computer computer = ComputerConverter.convertToPo(dto);
        Computer computerInDb = create(computer);
        return ComputerConverter.convertToModuleVo(computerInDb);
    }

    /**
     * 根据id获取电脑信息
     *
     * @param computerId computerId
     * @param allowNull  allowNull
     * @return
     */
    @Override
    public ComputerModuleVo getModuleVoById(String computerId, boolean allowNull) {
        Computer computer = computerPoService.getById(computerId, allowNull);
        return ComputerConverter.convertToModuleVo(computer);
    }

    /**
     * 根据id获取电脑信息
     *
     * @param computerId computerId
     * @param allowNull  allowNull
     * @return
     */
    @Override
    public ComputerVo getVoById(String computerId, boolean allowNull) {
        Computer computer = computerPoService.getById(computerId, allowNull);
        return ComputerConverter.convertToVo(computer);
    }

    /**
     * 根据编码获取电脑信息
     *
     * @param computerCode computerCode
     * @param allowNull    allowNull
     * @return
     */
    @Override
    public ComputerModuleVo getModuleVoByCode(String computerCode, boolean allowNull) {
        Computer computer = computerPoService.getByCode(computerCode, allowNull);
        return ComputerConverter.convertToModuleVo(computer);
    }

    /**
     * 电脑信息分页查询
     *
     * @param dto dto
     * @return
     */
    @Override
    public PageVo<ComputerVo> page(ComputerPageQueryDto dto) {
        Page<Computer> page = computerPoService.page(dto);
        return PagePoUtil.convertToPageVo(page, ComputerConverter::convertToVo);
    }
}